home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hot Super Models
/
Hot Super Models.iso
/
unix
/
x11
/
xv200.tar
/
xv-2.00
/
xvimage.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-02
|
23KB
|
911 lines
/*
* xvimage.c - image manipulation functions (crop,resize,rotate...) for XV
*
* Author: John Bradley, University of Pennsylvania
* (bradley@cis.upenn.edu)
*
* Contains:
* void Resize(int, int)
* void DoCrop()
* static void DoCrop1(int, int, int, int)
* void UnCrop()
* void AutoCrop()
* void Rotate(int)
* static void RotatePic(byte *, int *, int *, int)
* static void FloydDitherize8(byte *)
* static void FloydDitherize1(XImage *)
* void FSDither(byte *, int, int, byte *)
* void CreateXImage()
*
*/
/*
* Copyright 1989, 1990, 1991, 1992 by John Bradley and
* The University of Pennsylvania
*
* Permission to use, copy, and distribute for non-commercial purposes,
* is hereby granted without fee, providing that the above copyright
* notice appear in all copies and that both the copyright notice and this
* permission notice appear in supporting documentation.
*
* The software may be modified for your own purposes, but modified versions
* may not be distributed.
*
* This software is provided "as is" without any express or implied warranty.
*
* The author may be contacted via:
* US Mail: John Bradley
* GRASP Lab, Room 301C
* 3401 Walnut St.
* Philadelphia, PA 19104
*
* Phone: (215) 898-8813
* EMail: bradley@cis.upenn.edu
*/
#include "xv.h"
#ifdef __STDC__
static void DoCrop1(int, int, int, int);
static void RotatePic(byte *, int *, int *, int);
static void FloydDitherize8(byte *);
static void FloydDitherize1(XImage *);
#else
static void DoCrop1(), RotatePic(), FloydDitherize8();
static void FloydDitherize1();
#endif
/***********************************/
void Resize(w,h)
int w,h;
{
int cy,ex,ey,*cxarr, *cxarrp;
byte *clptr,*elptr,*epptr;
static char *rstr = "Resizing Image. Please wait...";
clptr = NULL; cxarrp = NULL; cy = 0; /* shut up compiler */
RANGE(w,1,maxWIDE); RANGE(h,1,maxHIGH);
SetISTR(ISTR_EXPAND, "%.3g x %.3g (%d x %d)",
((float) w) / cWIDE, ((float) h) / cHIGH, w, h);
/* if same size, and Ximage created, do nothing */
if (w==eWIDE && h==eHIGH && theImage!=NULL) return;
if (DEBUG) fprintf(stderr,"%s: Resize(%d,%d) eSIZE=%d,%d cSIZE=%d,%d\n",
cmd,w,h,eWIDE,eHIGH,cWIDE,cHIGH);
BTSetActive(&but[BCROP],0);
SetCropString(but[BCROP].active);
epicmode = EM_RAW; SetEpicMode();
if (w==cWIDE && h==cHIGH) { /* 1:1 expansion. point epic at cpic */
if (epic != cpic && epic!=NULL) free(epic);
epic = cpic; eWIDE = cWIDE; eHIGH = cHIGH;
if (psUp) PSResize(); /* if PSDialog is open, mention size change */
}
else { /* have to actually SCALE THE PIC. Drats! */
WaitCursor();
/* if it's a big image, this could take a while. mention it,
but only if we're actually changing the size, and only if we're
not using the root window */
if (w*h>(500*500) && (w!=eWIDE || h!=eHIGH) && !useroot && mainW) {
XSetForeground(theDisp, theGC, fg);
XSetBackground(theDisp, theGC, bg);
XClearWindow(theDisp,mainW);
XFlush(theDisp);
XDrawImageString(theDisp,mainW,theGC,CENTERX(mfinfo,w/2,rstr),
CENTERY(mfinfo,h/2),rstr, strlen(rstr));
XFlush(theDisp);
}
/* first, kill the old epic, if one exists */
if (epic!=NULL && epic!=cpic) {
free(epic); epic = NULL;
}
/* create a new epic of the appropriate size */
eWIDE = w; eHIGH = h;
epic = (byte *) malloc(w*h);
if (epic==NULL) {
sprintf(str,"unable to malloc a %dx%d image\n",w,h);
FatalError(str);
}
if (psUp) PSResize(); /* if PSDialog is open, mention size change */
/* the scaling routine. not really all that scary after all... */
/* OPTIMIZATON IDEA. Malloc an eWIDE array of ints which will hold the
values of the equation px = (pWIDE * ex) / eWIDE. Faster than doing
a mul and a div for every point in picture */
cxarr = (int *) malloc(eWIDE * sizeof(int));
if (!cxarr) FatalError("unable to allocate cxarr");
for (ex=0; ex<eWIDE; ex++)
cxarr[ex] = (cWIDE * ex) / eWIDE;
elptr = epptr = epic;
for (ey=0; ey<eHIGH; ey++, elptr+=eWIDE) {
if ((ey&127) == 0) WaitCursor();
cy = (cHIGH * ey) / eHIGH;
epptr = elptr;
clptr = cpic + (cy * cWIDE);
for (ex=0, cxarrp = cxarr; ex<eWIDE; ex++, epptr++)
*epptr = clptr[*cxarrp++];
}
free(cxarr);
}
/* now make something displayable out of epic */
CreateXImage();
}
/***********************************/
void DoCrop()
{
int i, x, y, x2, y2, w, h;
if (!but[BCROP].active) return;
/* turn off the cropping rectangle */
InvCropRect(); BTSetActive(&but[BCROP],0);
/* sort crx1,crx2,cry1,cry2 so that crx1,cry1 are top left corner */
if (crx1>crx2) { i = crx1; crx1 = crx2; crx2 = i; }
if (cry1>cry2) { i = cry1; cry1 = cry2; cry2 = i; }
/* see if cropping to same size, in which case do nothing */
if (crx2-crx1 == eWIDE && cry2-cry1 == eHIGH) return;
/* figure out what the crop rectangles coordinates are in pic coordinates */
x = cXOFF + (crx1 * cWIDE) / eWIDE;
y = cYOFF + (cry1 * cHIGH) / eHIGH;
x2 = cXOFF + (crx2 * cWIDE) / eWIDE;
y2 = cYOFF + (cry2 * cHIGH) / eHIGH;
w = (x2 - x) + 1;
h = (y2 - y) + 1;
if (w<1) w = 1;
if (x+w > pWIDE) w = pWIDE - x;
if (h<1) h = 1;
if (y+h > pHIGH) h = pHIGH - y;
DoCrop1(x,y,w,h);
}
static void DoCrop1(x,y,w,h)
int x,y,w,h;
{
int i,j;
byte *cp, *pp;
double expw, exph;
epicmode = EM_RAW; SetEpicMode();
/* dispose of old cpic and epic */
if (epic && epic != cpic) free(epic);
if (cpic && cpic != pic) free(cpic);
epic = cpic = NULL;
expw = (double) eWIDE / (double) cWIDE;
exph = (double) eHIGH / (double) cHIGH;
crx1 = (int) ((x - cXOFF) * expw);
cry1 = (int) ((y - cYOFF) * exph);
cXOFF = x; cYOFF = y; cWIDE = w; cHIGH = h;
if (DEBUG) fprintf(stderr,"%s: cropping to %dx%d rectangle at %d,%d\n",
cmd, cWIDE, cHIGH, cXOFF, cYOFF);
/* kill old Ximage so that Resize will be forced to generate a new one */
if (theImage != NULL) XDestroyImage(theImage);
theImage = NULL;
/* at this point, we want to generate cpic, which will contain a
cWIDE*cHIGH subsection of 'pic', top-left at cXOFF,cYOFF */
cpic = (byte *) malloc(cWIDE * cHIGH);
if (cpic == NULL) {
fprintf(stderr,"%s: unable to allocate memory for cropped image\n", cmd);
WUnCrop();
cpic = pic; cXOFF = cYOFF = 0; cWIDE = pWIDE; cHIGH = pHIGH;
SetCropString(but[BCROP].active);
return;
}
/* copy relevant pixels from pic to cpic */
cp = cpic;
for (i=0; i<cHIGH; i++) {
pp = pic + (i+cYOFF) * pWIDE + cXOFF;
for (j=0; j<cWIDE; j++)
*cp++ = *pp++;
}
SetCropString(but[BCROP].active);
BTSetActive(&but[BUNCROP],1);
/* shrink window */
WCrop((int) (cWIDE * expw), (int) (cHIGH * exph));
}
/***********************************/
void UnCrop()
{
int w,h;
if (cpic == pic) return; /* not cropped */
BTSetActive(&but[BUNCROP],0);
epicmode = EM_RAW; SetEpicMode();
/* dispose of old cpic and epic */
if (epic && epic != cpic) free(epic);
if (cpic && cpic != pic) free(cpic);
epic = cpic = NULL;
/* kill old Ximage so that Resize will be forced to generate a new one */
if (theImage != NULL) XDestroyImage(theImage);
theImage = NULL;
w = (pWIDE * eWIDE) / cWIDE;
h = (pHIGH * eHIGH) / cHIGH;
RANGE(w,1,maxWIDE); RANGE(h,1,maxHIGH);
WUnCrop();
cpic = pic; cXOFF = cYOFF = 0; cWIDE = pWIDE; cHIGH = pHIGH;
SetCropString(but[BCROP].active);
}
/***********************************/
void AutoCrop()
{
byte *cp, *cp1;
int i, ctop, cbot, cleft, cright;
byte bgcol;
ctop = cbot = cleft = cright = 0;
/* crop the top */
cp = cpic;
bgcol = cp[0];
while (ctop+1 < cHIGH) {
/* see if we can delete this line */
for (i=0, cp1=cp; i<cWIDE && *cp1==bgcol; i++, cp1++);
if (i==cWIDE) { cp += cWIDE; ctop++; }
else break;
}
/* crop the bottom */
cp = cpic + (cHIGH-1) * cWIDE;
bgcol = cp[0];
while (ctop + cbot + 1 < cHIGH) {
/* see if we can delete this line */
for (i=0, cp1=cp; i<cWIDE && *cp1==bgcol; i++,cp1++);
if (i==cWIDE) { cp -= cWIDE; cbot++; }
else break;
}
/* crop the left side */
cp = cpic;
bgcol = cp[0];
while (cleft + 1 < cWIDE) {
/* see if we can delete this line */
for (i=0, cp1=cp; i<cHIGH && *cp1==bgcol; i++, cp1 += cWIDE);
if (i==cHIGH) { cp++; cleft++; }
else break;
}
/* crop the right side */
cp = cpic + cWIDE-1;
bgcol = cp[0];
while (cleft + cright + 1 < cWIDE) {
/* see if we can delete this line */
for (i=0, cp1=cp; i<cHIGH && *cp1==bgcol; i++, cp1 += cWIDE);
if (i==cHIGH) { cp--; cright++; }
else break;
}
/* do the actual cropping */
if (cleft || ctop || cbot || cright)
DoCrop1(cXOFF+cleft, cYOFF+ctop, cWIDE-(cleft+cright), cHIGH-(ctop+cbot));
}
/***********************************/
void Rotate(dir)
int dir;
{
int i;
/* dir=0: clockwise, else counter-clockwise */
WaitCursor();
RotatePic(pic, &pWIDE, &pHIGH, dir);
/* rotate clipped version and modify 'clip' coords */
if (cpic != pic && cpic != NULL) {
if (!dir) {
i = pWIDE - (cYOFF + cHIGH); /* have to rotate offsets */
cYOFF = cXOFF;
cXOFF = i;
}
else {
i = pHIGH - (cXOFF + cWIDE);
cXOFF = cYOFF;
cYOFF = i;
}
WaitCursor();
RotatePic(cpic, &cWIDE, &cHIGH,dir);
}
else { cWIDE = pWIDE; cHIGH = pHIGH; }
/* rotate expanded version */
if (epic != cpic && epic != NULL) {
WaitCursor();
RotatePic(epic, &eWIDE, &eHIGH,dir);
}
else { eWIDE = cWIDE; eHIGH = cHIGH; }
CreateXImage();
WRotate();
}
/************************/
static void RotatePic(pic, wp, hp, dir)
byte *pic;
int *wp, *hp;
int dir;
{
/* rotates a w*h array of bytes 90 deg clockwise (dir=0)
or counter-clockwise (dir != 0). swaps w and h */
byte *pic1, *pix1, *pix;
int i,j;
unsigned int w,h;
w = *wp; h = *hp;
pix1 = pic1 = (byte *) malloc(w*h);
if (!pic1) FatalError("Not enough memory to rotate!");
/* do the rotation */
if (dir==0) {
for (i=0; i<w; i++) /* CW */
for (j=h-1, pix=pic+(h-1)*w + i; j>=0; j--, pix1++, pix-=w)
*pix1 = *pix;
}
else {
for (i=w-1; i>=0; i--) /* CCW */
for (j=0, pix=pic+i; j<h; j++, pix1++, pix+=w)
*pix1 = *pix;
}
/* copy the rotated buffer into the original buffer */
memcpy(pic, pic1, w*h);
free(pic1);
/* swap w and h */
*wp = h; *hp = w;
}
/***********************************/
void Flip(dir)
int dir;
{
/* dir=0: flip horizontally, else vertically */
WaitCursor();
FlipPic(pic, pWIDE, pHIGH, dir);
/* flip clipped version */
if (cpic != pic && cpic != NULL) {
WaitCursor();
FlipPic(cpic, cWIDE, cHIGH, dir);
}
/* flip expanded version */
if (epic != cpic && epic != NULL) {
WaitCursor();
FlipPic(epic, eWIDE, eHIGH,dir);
}
CreateXImage();
if (mainW && !useroot) DrawWindow(0, 0, eWIDE, eHIGH);
}
/************************/
void FlipPic(pic, w, h, dir)
byte *pic;
int w, h;
int dir;
{
/* flips a w*h array of bytes horizontally (dir=0) or vertically (dir!=0) */
byte *plin;
int i,j,k;
if (dir==0) { /* horizontal flip */
for (i=0; i<h; i++) {
plin = pic + i*w;
for (j=0; j<w/2; j++) {
k = plin[j];
plin[j] = plin[w - 1 - j];
plin[w - 1 - j] = k;
}
}
}
else { /* vertical flip */
for (i=0; i<w; i++)
for (j=0; j<h/2; j++) {
k = pic[j*w + i];
pic[j*w + i] = pic[(h - 1 - j)*w + i];
pic[(h - 1 -j)*w + i] = k;
}
}
}
/************************/
static void FloydDitherize8(image)
byte *image;
{
/* takes epic, and builds a black&white dithered version of it.
stores result in 8bit Pixmap format in 'image' */
int i;
byte *p;
FSDither(epic, eWIDE, eHIGH, image);
/* set to 'black' and 'white' instead of '0' and '1' */
if (black != 0 || white != 1) {
for (i=eWIDE*eHIGH, p=image; i>0; i--, p++) {
if (*p) *p = white; else *p = black;
}
}
}
/************************/
static void FloydDitherize1(ximage)
XImage *ximage;
{
/* same as FloydDitherize8, but output is a 1-bit per pixel XYBitmap,
packed 8 pixels per byte */
register short *dp;
register byte pix8, bit;
short *dithpic;
int i, j, err, bperln, order;
byte *pp, *image, w1, b1, w8, b8, rgb[256];
/* first thing to do is build rgb[], which will hold the B/W intensity
of the colors in the r,g,b arrays */
for (i=0; i<256; i++)
rgb[i] = MONO(r[i], g[i], b[i]);
image = (byte *) ximage->data;
bperln = ximage->bytes_per_line;
order = ximage->bitmap_bit_order;
if (DEBUG) fprintf(stderr,"Ditherizing1...");
dithpic = (short *) malloc(eWIDE * eHIGH * sizeof(short));
if (dithpic == NULL) FatalError("not enough memory to ditherize");
w1 = white&0x1; b1=black&0x1;
w8 = w1<<7; b8 = b1<<7; /* b/w bit in high bit */
/* copy rgb[epic] into dithpic so that we can run the algorithm */
pp = epic; dp = dithpic;
for (i=eHIGH * eWIDE; i>0; i--) *dp++ = fsgamcr[rgb[*pp++]];
dp = dithpic;
pp = image;
for (i=0; i<eHIGH; i++) {
pp = image + i*bperln;
if ((i&63) == 0) WaitCursor();
if (order==LSBFirst) {
bit = pix8 = 0;
for (j=0; j<eWIDE; j++,dp++) {
if (*dp<128) { err = *dp; pix8 |= b8; }
else { err = *dp-255; pix8 |= w8; }
if (bit==7) {
*pp++ = pix8; bit=pix8=0;
}
else { pix8 >>= 1; bit++; }
if (j<eWIDE-1) dp[1] += ((err*7)/16);
if (i<eHIGH-1) {
dp[eWIDE] += ((err*5)/16);
if (j>0) dp[eWIDE-1] += ((err*3)/16);
if (j<eWIDE-1) dp[eWIDE+1] += (err/16);
}
}
if (bit) *pp++ = pix8>>(7-bit); /* write partial byte at end of line */
}
else { /* order==MSBFirst */
bit = pix8 = 0;
for (j=0; j<eWIDE; j++,dp++) {
if (*dp<128) { err = *dp; pix8 |= b1; }
else { err = *dp-255; pix8 |= w1; }
if (bit==7) {
*pp++ = pix8; bit=pix8=0;
}
else { pix8 <<= 1; bit++; }
if (j<eWIDE-1) dp[1] += ((err*7)/16);
if (i<eHIGH-1) {
dp[eWIDE] += ((err*5)/16);
if (j>0) dp[eWIDE-1] += ((err*3)/16);
if (j<eWIDE-1) dp[eWIDE+1] += (err/16);
}
}
if (bit) *pp++ = pix8<<(7-bit); /* write partial byte at end of line */
}
}
if (DEBUG) fprintf(stderr,"done\n");
free(dithpic);
}
/************************/
void FSDither(inpic, w, h, outpic)
byte *inpic, *outpic;
int w,h;
{
/* takes inpic, and builds a black&white dithered version of it.
stores result as 1 byte per pixel format in 'image'
black = 0; white = 1;
temporarily mallocs a w*h array of SHORTS.
(need to be signed, also to avoid overflow problems.) */
/* floyd-steinberg dithering.
*
* ---- x 7/16
* 3/16 5/16 1/16
*
*/
short *dp, *dithpic;
int i, j, err, w1, h1;
byte *pp, rgb[256];
if (DEBUG) fprintf(stderr,"Ditherizing...");
/* first thing to do is build rgb[], which will hold the B/W intensity
of the colors in the r,g,b arrays */
for (i=0; i<256; i++)
rgb[i] = MONO(r[i], g[i], b[i]);
dithpic = (short *) malloc(w*h * sizeof(short));
if (dithpic == NULL) FatalError("not enough memory to ditherize");
w1 = w-1; h1 = h-1;
/* copy rgb[inpic] into dithpic so that we can run the algorithm */
pp = inpic; dp = dithpic;
for (i=w*h; i>0; i--) *dp++ = fsgamcr[rgb[*pp++]];
dp = dithpic; pp = outpic;
for (i=0; i<h; i++) {
if ((i&15) == 0) WaitCursor();
for (j=0; j<w; j++,dp++,pp++) {
if (*dp<128) { err = *dp; *pp = 0; }
else { err = *dp-255; *pp = 1; }
if (j<w1) dp[1] += ((err*7)/16);
if (i<h1) {
dp[w] += ((err*5)/16);
if (j>0) dp[w1] += ((err*3)/16);
if (j<w1) dp[w+1] += (err/16);
}
}
}
if (DEBUG) fprintf(stderr,"done\n");
free(dithpic);
}
/***********************************/
void CreateXImage()
{
int i;
/*
* this has to do the tricky bit of converting the data in 'epic'
* into something usable for X.
*
* Algorithm notes:
* if dispDEEP is 8, nothing has to be done other than create an
* Ximage (ZPixmap, depth=8) and point it at the 'epic' data.
*
* if dispDEEP is 1, format'll be an XYBitmap, special case code
*
* if dispDEEP is 4, format'll be a ZPixmap, 4 or 8 bits per pixel
*
* if dispDEEP is 6, format'll be a ZPixmap, 8 bits per pixel
*
* if dispDEEP is 16, format'll be a ZPixmap, 16 bits per pixel
*
* if dispDEEP is 24 or 32, format'll be a ZPixmap. 32 bits per pixel
*
*/
if (DEBUG)
fprintf(stderr,"%s: creating a %dx%d Ximage, %d bits deep\n",
cmd, eWIDE, eHIGH, dispDEEP);
/* destroy old image and imagedata, if there is one */
if (theImage) XDestroyImage(theImage);
theImage = NULL;
if (!epic) {
/* fprintf(stderr,"CreateXImage called while epic was null\n"); */
Resize(eWIDE,eHIGH);
return;
}
switch (dispDEEP)
{
case 8:
{
byte *imagedata, *ip, *pp;
imagedata = (byte *) malloc(eWIDE*eHIGH);
if (!imagedata) FatalError("couldn't malloc imagedata");
if (ncols==0) FloydDitherize8(imagedata);
else {
for (i=eWIDE*eHIGH, pp=epic, ip=imagedata; i>0; i--,pp++,ip++) {
if ((i&0x1ffff) == 0) WaitCursor();
*ip = (byte) cols[*pp];
}
}
theImage = XCreateImage(theDisp,theVisual,dispDEEP,ZPixmap,0,
(char *) imagedata, eWIDE, eHIGH, 8, 0);
if (!theImage) FatalError("couldn't create theImage!");
}
break;
/*********************************/
case 1:
{
byte *imagedata;
theImage = XCreateImage(theDisp, theVisual, dispDEEP, XYPixmap, 0, NULL,
eWIDE, eHIGH, 8, 0);
if (!theImage) FatalError("couldn't create theImage!");
imagedata = (byte *) malloc(theImage->bytes_per_line * eHIGH);
if (!imagedata) FatalError("couldn't malloc imagedata");
theImage->data = (char *) imagedata;
FloydDitherize1(theImage);
}
break;
/*********************************/
case 4: {
byte *imagedata, *ip, *pp;
byte *lip;
int bperline, half, j;
theImage = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
eWIDE, eHIGH, 8, 0);
if (!theImage) FatalError("couldn't create theImage!");
bperline = theImage->bytes_per_line;
imagedata = (byte *) malloc(bperline * eHIGH);
if (!imagedata) FatalError("couldn't malloc imagedata");
theImage->data = (char *) imagedata;
if (ncols==0) { /* ditherize */
byte *dith;
dith = (byte *) malloc(eWIDE * eHIGH);
if (!dith) FatalError("can't create dithered image");
FloydDitherize8(dith);
if (theImage->bits_per_pixel == 4) {
for (i=0, pp=dith, lip=imagedata; i<eHIGH; i++, lip+=bperline)
for (j=0, ip=lip, half=0; j<eWIDE; j++,pp++,half++) {
if (theImage->bitmap_bit_order == LSBFirst) {
if (half&1) { *ip = *ip + ((*pp&0x0f)<<4); ip++; }
else *ip = *pp&0x0f;
}
else {
if (half&1) { *ip = *ip + (*pp&0x0f); ip++; }
else *ip = (*pp&0x0f) << 4;
}
}
}
else if (theImage->bits_per_pixel == 8)
memcpy(imagedata, dith, eWIDE*eHIGH);
else FatalError("This display is too bizarre. Can't create XImage.");
free(dith);
}
else { /* don't ditherize */
if (theImage->bits_per_pixel == 4) {
for (i=0, pp=epic, lip=imagedata; i<eHIGH; i++, lip+=bperline) {
if ((i&127) == 0) WaitCursor();
for (j=0, ip=lip, half=0; j<eWIDE; j++,pp++,half++) {
if (theImage->bitmap_bit_order == LSBFirst) {
if (half&1) { *ip = *ip + ((cols[*pp]&0x0f)<<4); ip++; }
else *ip = cols[*pp]&0x0f;
}
else {
if (half&1) { *ip = *ip + (cols[*pp]&0x0f); ip++; }
else *ip = (cols[*pp]&0x0f) << 4;
}
}
}
}
else if (theImage->bits_per_pixel == 8) {
for (i=eWIDE*eHIGH, pp=epic, ip=imagedata; i>0; i--,pp++,ip++) {
if ((i&0x1ffff) == 0) WaitCursor();
*ip = (byte) cols[*pp];
}
}
else FatalError("This display's too bizarre. Can't create XImage.");
}
}
break;
/*********************************/
case 6: {
byte *imagedata, *ip, *pp;
int bperline;
theImage = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL,
eWIDE, eHIGH, 8, 0);
if (!theImage) FatalError("couldn't create theImage!");
if (theImage->bits_per_pixel != 8)
FatalError("This display's too bizarre. Can't create XImage.");
bperline = theImage->bytes_per_line;
imagedata = (byte *) malloc(bperline * eHIGH);
if (!imagedata) FatalError("couldn't malloc imagedata");
theImage->data = (char *) imagedata;
if (ncols==0) FloydDitherize8(imagedata);
else {
for (i=eWIDE*eHIGH, pp=epic, ip=imagedata; i>0; i--,pp++,ip++) {
if ((i&0x1ffff) == 0) WaitCursor();
*ip = (byte) cols[*pp];
}
}
}
break;
/*********************************/
case 16: {
short *imagedata, *ip;
byte *pp;
imagedata = (short *) malloc(2*eWIDE*eHIGH);
if (!imagedata) FatalError("couldn't malloc imagedata");
theImage = XCreateImage(theDisp,theVisual,dispDEEP,ZPixmap,0,
(char *) imagedata, eWIDE, eHIGH, 16, 0);
if (!theImage) FatalError("couldn't create theImage!");
if (theImage->byte_order == MSBFirst)
for (i=eWIDE*eHIGH, pp=epic, ip=imagedata; i>0; i--,pp++) {
if ((i&0x1ffff) == 0) WaitCursor();
*ip++ = cols[*pp] & 0xffff;
}
else
for (i=eWIDE*eHIGH, pp=epic, ip=imagedata; i>0; i--,pp++) {
if ((i&0x1ffff) == 0) WaitCursor();
*ip++ = ((cols[*pp] >> 8) & 0xff) | ((cols[*pp] & 0xff) >> 8);
}
}
break;
/*********************************/
case 24:
case 32:
{
byte *imagedata, *ip, *pp;
imagedata = (byte *) malloc(4*eWIDE*eHIGH);
if (!imagedata) FatalError("couldn't malloc imagedata");
theImage = XCreateImage(theDisp,theVisual,dispDEEP,ZPixmap,0,
(char *) imagedata, eWIDE, eHIGH, 32, 0);
if (!theImage) FatalError("couldn't create theImage!");
if (theImage->byte_order == MSBFirst)
for (i=eWIDE*eHIGH, pp=epic, ip=imagedata; i>0; i--,pp++) {
if ((i&0x1ffff) == 0) WaitCursor();
*ip++ = 0;
*ip++ = (cols[*pp]>>16) & 0xff;
*ip++ = (cols[*pp]>>8) & 0xff;
*ip++ = cols[*pp] & 0xff;
}
else
for (i=eWIDE*eHIGH, pp=epic, ip=imagedata; i>0; i--,pp++) {
if ((i&0x1ffff) == 0) WaitCursor();
*ip++ = cols[*pp] & 0xff;
*ip++ = (cols[*pp]>>8) & 0xff;
*ip++ = (cols[*pp]>>16) & 0xff;
*ip++ = 0;
}
}
break;
/*********************************/
default:
sprintf(str,"no code to handle this display type (%d bits deep)",
dispDEEP);
FatalError(str);
break;
}
}